<?php

namespace App\Http\Controllers\Api\Orders;

use App\Http\Controllers\Controller;
use App\Http\Requests\Train\Order\RequiredOrderSnRequest;
use App\Models\Common\Channel\Repositories\Interfaces\ChannelRepositoryInterface;
use App\Models\Orders\Orders;
use App\Models\Scenic\Order\ScenicOrderGoods;
use App\Models\Scenic\Order\ScenicOrderPassenger;
use App\Models\Scenic\Order\ScenicOrderRepository;
use App\Models\Scenic\ScenicOrder;
use App\Models\Scenic\ScenicSpotGoods;
use App\Models\Trip\OrderPay\Repositories\Interfaces\OrderPayRepositoryInterface;
use App\Services\Scenic\ScenicOrderFactory;
use App\Trip\Enums\Scenic\ScenicProvider;
use App\Trip\Enums\TripTypes;
use App\Trip\Orders\BookOrders\BookOrdersManager;
use App\Trip\Orders\TripOrderState;
use App\Trip\Payment\PaymentAttach;
use App\Trip\Wechat\AppId;
use App\Trip\Wechat\Pay\WechatPay;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use TencentCloud\Cpdp\V20190820\Models\Order;

class ScenicOrdersController extends Controller
{

    private OrderPayRepositoryInterface $orderPayRepo;
    private string|int|null $user_id;
    private WechatPay $wechatPay;
    private string $appId;
    private ScenicOrderRepository       $scenicOrderRepo;
    public function __construct(
        OrderPayRepositoryInterface    $orderPayRepository,
        ScenicOrderRepository    $scenicOrderRepo
    )
    {
        $this->user_id = auth()->id();
        $this->orderPayRepo       = $orderPayRepository;
        $this->scenicOrderRepo    = $scenicOrderRepo;
        $this->appId              = AppId::getAppId();
        $this->wechatPay          = new WechatPay(['appid' => $this->appId]);
    }

    public function book(Request $request)
    {
        $requestdata = $request->all();
        $order_data = $requestdata['order'] ?? [];
        $order_data['user_id'] = $this->user_id;
        Log::info(json_encode(['method' => '门票订票', 'request' => $request->all()], JSON_UNESCAPED_UNICODE));
        $order_manager = new BookOrdersManager($order_data);
        try {
            $orderInfoData = $order_manager->scenic_book($requestdata);
        } catch (\Exception $exception) {
            return $this->error($exception->getCode(), $exception->getMessage());
        }

        return $this->success('success', $orderInfoData);
    }

    public function refund_apply(Request $request)
    {
        $requestdata = $request->all();
        $order_sn = $requestdata['order_sn'] ?? '';
        $refund_type = $requestdata['refund_type'] ?? 0;
        $refund_msg = $requestdata['refund_msg'] ?? '';
        if (empty($order_sn)){
            return  $this->error(404,'参数错误');
        }

    }


    public function cancel_order(RequiredOrderSnRequest $request)
    {
        $order_sn = $request->input('order_sn','');
        if (empty($order_sn)){
            return $this->error(404,'参数错误');
        }
        $order = Orders::whereOrderSn($order_sn)->where('user_id',auth()->id())->first();
        if (!$order instanceof Orders){
            return $this->error(404,'参数错误');
        }
        if ($order->isDelete()){
            return  $this->error(404,'订单已删除');
        }
        if (in_array($order->getOrderState(),TripOrderState::canceled_order_states())){
            return  $this->error(404,'订单已取消，请勿重复操作');
        }
        if ($order->getOrderState() == TripOrderState::ORDER_STATE_PAID){
            return  $this->error(404,'订单已支付，不可取消');
        }

        $scenic_order = ScenicOrder::where('order_sn',$order->getOrderSn())->first();

        $provider = ScenicProvider::from($scenic_order->order_service);
        $scenicOrderProvider = (new ScenicOrderFactory())->findOneByProvider($provider);
        $providerOrderState = $scenicOrderProvider->orderStatus(['out_order_id'=>$scenic_order->out_order_id]);
        if (in_array($providerOrderState,$scenic_order->disableStates())){
            return  $this->error(404,'订单已出票或已完成，不可取消');
        }

        DB::transaction(function () use ($order) {
            $curryTime = date('Y-m-d H:i:s');
            $order->delete_state = TripOrderState::ORDER_STATE_MANUAL_CANCEL;
            $order->updated_at = $curryTime;
            $order->save();
            ScenicOrder::where('order_sn',$order->getOrderSn())->update([
                'delete_state'=>TripOrderState::ORDER_STATE_MANUAL_CANCEL,
                'updated_at'=>$curryTime
            ]);
        });

        return $this->success();
    }



    public function delete(RequiredOrderSnRequest $request)
    {
        $order_sn = $request->input('order_sn','');
        if (empty($order_sn)){
            return $this->error(404,'参数错误');
        }
        $order = Orders::whereOrderSn($order_sn)->where('user_id',auth()->id())->first();
        if (!$order instanceof Orders){
            return $this->error(404,'参数错误');
        }
        if ($order->isDelete()){
            return  $this->error(404,'订单已删除，请勿重复操作');
        }
        if (!$order->canDelete()){
            return $this->error(404,'订单不属于可以删除状态');
        }

        DB::transaction(function () use ($order) {
            $deleteTime = Carbon::now()->toDateTimeString();
            $order->delete_state = TripOrderState::DELETE_STATE_DELETED;
            $order->deleted_at = $deleteTime;
            $order->save();
            ScenicOrder::where('order_sn',$order->getOrderSn())->update([
                'delete_state'=>TripOrderState::DELETE_STATE_DELETED,
                'delete_desc'=>"手动删除订单",
                'deleted_at'=>$deleteTime,
            ]);
        });

        return $this->success();
    }


    public function pay_info(RequiredOrderSnRequest $request)
    {

        $order_info = ScenicOrder::where('order_sn',$request->input('order_sn'))->first();
        if (!$order_info || $order_info->user_id != auth()->id()) {
            return $this->error(404, "订单不存在");
        }
        Log::info("请求订单支付：{$order_info->order_sn}");
        if ($order_info->order_state == 30) {
            return $this->error(1, "订单已取消");
        }


        if ($order_info->order_state != 0 || $order_info->delete_state == 1) {
            return $this->error(1, "订单不可支付");
        }

        // 获取支付信息
        $channelRepo = app(ChannelRepositoryInterface::class);
        $pay_info    = $this->orderPayRepo->createScenicOrderPayInfo($order_info, $this->wechatPay,
            $channelRepo->findChannelByAppId($this->appId));

        // 暂时不考虑单独支付
        $out_trade_no = $pay_info->getPaySn();
        $description  = $pay_info->getPayTitle();
        $maxPayAt = strtotime('+1hour',strtotime($order_info->created_at));
        $time_expire  = Carbon::parse($maxPayAt)->toRfc3339String();

        /**
         * 构造 attach 返回用于判别 发起支付的 级别 如果是飞机 则飞机可以独立支付
         *
         * @var $attach string type =>trip_type,os =>order_sn
         */
        $attach                   = new PaymentAttach([
            'type'     => PaymentAttach::PAY_TYPE_ORDER,  //下单
            'order_sn' => $order_info->getOrderSn(),
        ]);
        $payData                  = [
            "out_trade_no" => $out_trade_no,
            "description"  => $description,
            "time_expire"  => $time_expire,
            "order_amount" => $pay_info->getPayAmount(),
            "attach"       => $attach,
        ];
        $pay_info                 = $this->get_pay_info($payData);
        $pay_info['order_amount'] = $payData['order_amount'];
        return $this->success('', compact('pay_info'));

    }


    public function detail(RequiredOrderSnRequest $request)
    {
        $order_sn = $request->input('order_sn','');
        if (empty($order_sn)){
            return $this->error(404,'参数错误');
        }
        $order = Orders::whereOrderSn($order_sn)->where('user_id',auth()->id())->first();
        if (!$order instanceof Orders){
            return $this->error(404,'参数错误');
        }
        try {
            $data = $this->scenicOrderRepo->setOrderShowData($order);
        }catch (\Exception $exception){
            return $this->error($exception->getCode(),$exception->getMessage());
        }
        return $this->success('success', $data);
    }

    public function lists(Request $request)
    {

    }

}
